package com.hzit.cart.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.hzit.cart.dao.ItemDao;
import com.hzit.cart.entity.Item;
import com.hzit.cart.entity.OrderItem;
import com.hzit.cart.entity.group.Cart;
import com.hzit.cart.service.CartService;
import com.hzit.common.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@Service
public class CartServiceImpl implements CartService {
	@Autowired
	private StringRedisTemplate redisTemplate;
	@Autowired
	private ItemDao itemDao;
	@Autowired
	private IdWorker idWorker;

	//1. 添加商品到购物车列表中
	@Override
	public void add(String itemId, int num, String name) {
		//1.0 定义存放购物车旬表的集合
		List<Cart> cartList ;
		//1.1 从redis中取出购物车列表
		String cartListStr = (String) redisTemplate.opsForHash().get("cartList", name);
		//1.2 如果有值就转换
		if(StrUtil.isNotBlank(cartListStr)){
			cartList = JSON.parseArray(cartListStr,Cart.class);
		}else{
			cartList = new ArrayList<>();
		}
		//1.3 根据ItemId查询sku商品
		Item item = itemDao.selectById(itemId);
		//1.3.1 获取到商家id
		String sellerId = item.getSellerId();
		//1.3.2 根据商家id查找出购物车
		Cart cart = findCartBySellerId(sellerId,cartList);
		//1.4 判断购物车是否存在，
		if(cart != null){   //1.4.1 如果存在，就在其中的购物项中查询是否有此商品
			OrderItem orderItem = findOrderItemByItemId(itemId,cart.getOrderItemList());
			//1.4.2 如果找到了此商品，就修改其小计和数量
			if(orderItem != null){
				//① 修改数量
				orderItem.setNum(orderItem.getNum() + num);
				//② 修改小计金额
				orderItem.setTotalFee(new BigDecimal(orderItem.getPrice().doubleValue() * orderItem.getNum()));
			}else{  //1.4.3 如果找不到，就重新构造一个新的订单项商品并添加到购物项列表中
				orderItem = createOrderItem(item,num);
				cart.getOrderItemList().add(orderItem);
			}
		}else{          //1.4.2 如果不存在，就创建一个购物车，并把此购物车添加到购物车列表中
				cart = createCart(item,num);
				// 1.4.3 将购物车添加到购物车列表中
				cartList.add(cart);
		}
		//1.4 处理几种特殊情况
		//1.4.1 如果购物车中的购物项集合中的某件商品数量为0，就从购物项集合中移除此商品
		cart.getOrderItemList().removeIf(orderItem -> orderItem.getNum() == 0);
		//1.4.2 如果某件购物车的购物项中没有数据了，就从购物车列表中移除此购物车
		cartList.removeIf(c -> c.getOrderItemList().size() == 0);
		//1.5 将购物车添加到redis中
		redisTemplate.opsForHash().put("cartList",name,JSON.toJSONString(cartList));
	}

	//2. 根据sellerId查询出购物车
	private Cart findCartBySellerId(String sellerId, List<Cart> cartList) {
		for (Cart cart : cartList) {
			if(sellerId.equals(cart.getSellerId())){
				return cart;
			}
		}
		return null;
	}
	//3. 在购物车的购物项列表中根据sku商品id查询是否存在购物项商品
	private OrderItem findOrderItemByItemId(String itemId, List<OrderItem> orderItemList) {
		Long id = Long.parseLong(itemId);
		for (OrderItem orderItem : orderItemList) {
			if(id.longValue() == orderItem.getItemId().longValue()){
				return orderItem;
			}
		}
		return null;
	}
	//4. 创建购物项
	private OrderItem createOrderItem(Item item, int num) {
		//4.1 定义一个OrderItem对象
		OrderItem orderItem = new OrderItem();
		orderItem.setNum(num);
		orderItem.setGoodsId(item.getGoodsId());
		orderItem.setItemId(item.getId());
		orderItem.setPicPath(item.getImage());
		long id = idWorker.nextId();
		orderItem.setOrderId(id);
		long orderItemId = idWorker.nextId();
		orderItem.setId(orderItemId);
		orderItem.setSellerId(item.getSellerId());
		orderItem.setTitle(item.getTitle());
		orderItem.setPrice(item.getPrice());
		orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * num));
		//4.2 返回
		return orderItem;
	}
	//5. 创建一个新的购物车
	private Cart createCart(Item item, int num) {
		//5.1 创建一个购物车
		Cart cart = new Cart();
		//5.2 创建一个新的集合用于存放购物项休合
		List<OrderItem> orderItems = new ArrayList<>();
		//5.3 创建一个订单项商品
		OrderItem orderItem = createOrderItem(item,num);
		//5.4 将上面的订单项添加到集合中
		orderItems.add(orderItem);
		//5.5 将购物项集合与购物车绑定
		cart.setOrderItemList(orderItems);
		cart.setSellerId(item.getSellerId());
		cart.setSellerName(item.getSeller());
		//5.6 返回购物车对象
		return cart;
	}

	//6. 从redis中取得购物车列表
	@Override
	public List<Cart> getCartList(String name) {
		//6.1 从redis中得到购物车字符串
		if(StrUtil.isNotBlank(name)){
			String cartListStr = (String) redisTemplate.opsForHash().get("cartList", name);
			if(StrUtil.isNotBlank(cartListStr)){
				return JSON.parseArray(cartListStr,Cart.class);
			}
		}

		//6.2 转换并返回
		return new ArrayList<>();
	}
}
